home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Suzy B Software 2
/
Suzy B Software CD-ROM 2 (1994).iso
/
extras
/
programm
/
gemfsc20
/
gemfsc20.lzh
/
GEMFUNCS
/
FRMDIAL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-20
|
11KB
|
442 lines
/**************************************************************************
*
*************************************************************************/
#include "gemfintl.h"
/*----------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
static XUBT_STATUS maybe_touch_object __PROTO((OBJECT *ptree, short obj));
static short call_system_form_do __PROTO((FormControl *ctl));
static short find_mover_object __PROTO((OBJECT *ptree));
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
#define NO_FLAGS (-1)
#define BLITOPTIONS (FRM_USEBLIT|FRM_MOVEABLE)
#define CTL_ALLOCATED 0x80000000L
long _FrmDefaults = FRM_NORMAL;
long (*_FrBltVector) __PROTO((short options, void *buffer, void *rect));
static short (*default_form_do) __PROTO((FormControl *ctl)) = call_system_form_do;
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
static short call_system_form_do(ctl)
register FormControl *ctl;
{
return form_do(ctl->ptree, ctl->editobj);
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
static XUBT_STATUS maybe_touch_object(ptree, obj)
OBJECT *ptree;
short obj;
{
OBJECT *pobj;
XUSERBLK *xub;
short clicks;
short mx;
short my;
short dmy;
clicks = (obj & 0x8000) ? 2 : 1;
obj &= 0x7FFF;
pobj = &ptree[obj];
if (pobj->ob_flags & INDIRECT) {
xub = *(XUSERBLK **)pobj->ob_spec;
} else {
xub = (XUSERBLK *)pobj->ob_spec;
}
if ((pobj->ob_type & 0x00FF) == G_USERDEF &&
(xub->ub_self == xub) &&
(xub->ub_touch != NULL)) {
graf_mkstate(&mx, &my, &dmy, &dmy);
return (*xub->ub_touch)(xub, mx, my, clicks);
}
return XUBT_NONE;
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
static short find_mover_object(ptree)
register OBJECT *ptree;
{
register OBJECT *pobj = ptree;
register short obj = 0;
register short ob_flags;
for (;;) {
ob_flags = pobj->ob_flags;
if (ob_flags & FRM_MOVER) {
return obj;
}
if (ob_flags & LASTOB) {
return NO_OBJECT;
}
++obj;
++pobj;
}
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
FormControl *_FrmSetup(ctl, options, ptree, pboundrect)
register FormControl *ctl;
register long options;
register OBJECT *ptree;
register GRECT *pboundrect;
{
if (pboundrect == NULL) {
pboundrect = &gl_rwdesk;
}
if (!(options & FRM_NODEFAULTS)) {
options |= _FrmDefaults;
}
ctl->ptree = ptree;
ctl->pboundrect = pboundrect;
ctl->options = options & FRM_OPTIONBITS;
ctl->form_do = default_form_do;
ctl->editobj = ROOT;
ctl->parentobj = ROOT;
ctl->moverobj = NO_OBJECT;
ctl->treeflags = NO_FLAGS;
ctl->select_state = SELECTED;
ctl->blitbuffer = NULL;
if (options & FRM_DSTART) {
if (options & FRM_NEARMOUSE) {
short mx, my, dmy;
graf_mkstate(&mx, &my, &dmy, &dmy);
ptree->ob_x = mx - (ptree->ob_width / 2);
ptree->ob_y = my - (ptree->ob_height / 2);
frm_confine(ptree, pboundrect);
} else if (options & FRM_CENTER) {
frmx_center(ptree, &ctl->scrnrect);
}
}
frm_sizes(ptree, &ctl->scrnrect);
rc_scale(&ctl->scrnrect, &ctl->littlerect, 20);
if (options & FRM_DSTART) {
if ((options & BLITOPTIONS) && _FrBltVector != NULL) {
long blitbytes;
blitbytes = (*_FrBltVector)(GRF_BMEMCALC, NULL, &ctl->scrnrect);
if (NULL != (ctl->blitbuffer = apl_malloc(blitbytes))) {
ctl->moverobj = find_mover_object(ptree);
if (ctl->moverobj == NO_OBJECT && (options & FRM_MOVEABLE)) {
ctl->moverobj = ROOT;
ctl->treeflags = frm_mkmoveable(ptree, ROOT);
}
}
}
}
return ctl;
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
void frm_cleanup(ctl)
register FormControl *ctl;
{
if (ctl != NULL) {
if (ctl->blitbuffer != NULL) {
apl_free(ctl->blitbuffer);
}
if (ctl->ptree != NULL && ctl->treeflags != NO_FLAGS) {
ctl->ptree->ob_flags = ctl->treeflags;
}
if (ctl->options & CTL_ALLOCATED) {
apl_free(ctl);
}
}
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
FormControl *frm_init(options, ptree, pboundrect)
long options;
OBJECT *ptree;
GRECT *pboundrect;
{
FormControl *ctl;
if (NULL == (ctl = apl_malloc((long)sizeof(FormControl)))) {
return NULL;
} else {
_FrmSetup(ctl, options|FRM_DSTART, ptree, pboundrect);
ctl->options |= CTL_ALLOCATED;
return ctl;
}
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
void frm_start(ctl)
register FormControl *ctl;
{
if (ctl->blitbuffer != NULL) {
(*_FrBltVector)(GRF_BFROMSCREEN, ctl->blitbuffer, &ctl->scrnrect);
}
frmx_dial(FMD_START, &ctl->littlerect, &ctl->scrnrect);
if (ctl->options & FRM_EXPLODE) {
frmx_dial(FMD_GROW, &ctl->littlerect, &ctl->scrnrect);
}
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
void frm_draw(ctl, obj)
register FormControl *ctl;
short obj;
{
objc_draw(ctl->ptree, obj, MAX_DEPTH, RECTVALS(ctl->pboundrect));
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
void frm_finish(ctl)
register FormControl *ctl;
{
if (ctl->options & FRM_EXPLODE) {
frmx_dial(FMD_SHRINK, &ctl->littlerect, &ctl->scrnrect);
}
if (ctl->blitbuffer != NULL) {
(*_FrBltVector)(GRF_BTOSCREEN, ctl->blitbuffer, &ctl->scrnrect);
} else {
frmx_dial(FMD_FINISH, &ctl->littlerect, &ctl->scrnrect);
evnx_timer(1L);
}
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
void frm_move(ctl)
register FormControl *ctl;
{
short oldmouse;
short mb;
short dmy;
register short adjust;
register GRECT *prect = (GRECT *)&ctl->ptree->ob_x;
if (ctl->blitbuffer == NULL) {
return;
}
/*
* delay very briefly, then see if the mouse button is still down.
* if it's not, just return. this prevents false 'moves' when all
* the user did was miss the button s/he was after.
*/
evnx_timer(75L);
graf_mkstate(&dmy, &dmy, &mb, &dmy);
if (!mb) {
return;
}
(*_FrBltVector)(GRF_BTOSCREEN, ctl->blitbuffer, &ctl->scrnrect);
adjust = obj_clcalc(ctl->ptree, ROOT, NULL, NULL);
rc_gadjust(prect, adjust, adjust);
oldmouse = graf_mouse(FLAT_HAND, NULL);
grfx_dragbox(prect, ctl->pboundrect, prect);
graf_mouse(oldmouse, NULL);
adjust = -adjust;
rc_gadjust(prect, adjust, adjust);
frm_sizes(ctl->ptree, &ctl->scrnrect);
(*_FrBltVector)(GRF_BFROMSCREEN, ctl->blitbuffer, &ctl->scrnrect);
frm_draw(ctl, ROOT);
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
short frm_do(ctl, editobj)
register FormControl *ctl;
short editobj;
{
short oldmouse;
short more_interaction;
short rv;
short obj;
XUBT_STATUS status;
if (ctl->options & FRM_MOUSEARROW) {
oldmouse = graf_mouse(ARROW, 0L);
}
ctl->editobj = editobj;
do {
more_interaction = FALSE;
obj = 0x7FFF & (rv = (*ctl->form_do)(ctl));
if (rv == NO_OBJECT) {
goto QUICK_EXIT;
}
if (obj == ctl->moverobj) {
more_interaction = TRUE;
frm_move(ctl);
}
if (ctl->ptree[obj].ob_flags & TOUCHEXIT) {
if (ctl->ptree[obj].ob_state & DISABLED) {
more_interaction = TRUE;
} else {
if ((ctl->ptree[obj].ob_type & 0x00FF) == G_USERDEF) {
more_interaction = TRUE;
status = maybe_touch_object(ctl->ptree, rv);
if (status & XUBT_DCEXIT) {
if (NO_OBJECT != (rv = obj = obj_dxfind(ctl->ptree))) {
more_interaction = FALSE;
}
}
}
}
}
} while (more_interaction);
if (ctl->ptree[obj].ob_flags & (EXIT|DEFAULT)) {
evnx_timer(70L);
obj_stchange(ctl->ptree, obj, ~ctl->select_state,
OBJ_CLIPDRAW, ctl->pboundrect);
}
QUICK_EXIT:
if (ctl->options & FRM_MOUSEARROW) {
graf_mouse(oldmouse, 0L);
}
return rv;
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
short frm_dialog(options, ptree, object)
long options;
OBJECT *ptree;
short object;
{
FormControl ctl;
short selobj;
long actions;
if (0 == (actions = options & FRM_ACTIONBITS)) {
options |= (actions = FRM_DCOMPLETE);
}
if (actions == FRM_DCOMPLETE) {
wind_update(BEG_UPDATE);
} else {
if (options & BLITOPTIONS) {
options &= ~BLITOPTIONS;
}
}
_FrmSetup(&ctl, options, ptree, NULL);
if (actions & FRM_DSTART) {
frm_start(&ctl);
}
if (actions & FRM_DDRAW) {
frm_draw(&ctl, (options & FRM_DSTART) ? ROOT : object);
}
if (actions & FRM_DDO) {
selobj = frm_do(&ctl, object);
}
if (actions & FRM_DFINISH) {
frm_finish(&ctl);
}
frm_cleanup(&ctl);
if (actions == FRM_DCOMPLETE) {
wind_update(END_UPDATE);
}
return selobj;
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
long frm_defaults(options)
long options;
{
long rv = _FrmDefaults;
if (options != FRM_GETDEFAULTS) {
_FrmDefaults = options & FRM_OPTIONBITS & ~FRM_NODEFAULTS;
}
return rv;
}
/*-------------------------------------------------------------------------
*
*-----------------------------------------------------------------------*/
void *frm_dovector(newfunc)
void *newfunc;
{
void *rv = default_form_do;
if (newfunc != NULL) {
default_form_do = newfunc;
}
return rv;
}